package third

import (
	"time"
	"fmt"
	"net/http"
	"io/ioutil"
	"encoding/json"
	"errors"
	"strconv"
)
// 微信相关接口
const (
	WX_JSURL 	= "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"
	WX_OAUTH2	= "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"
)

// 小程序获取 openId, sessionKey, unionid
// jscode: 由小程序传递过来的登录凭证
// openid 	string 	用户唯一标识
// session_key 	string 	会话密钥
// unionid 	string 	用户在开放平台的唯一标识符，若当前小程序已绑定到微信开放平台帐号下会返回，详见 UnionID 机制说明。
// errcode 	number 	错误码
// errmsg 	string 	错误信息
func GetWxJsOpenId(appId string, scret string, jscode string) (string, string, string, error) {
	url := fmt.Sprintf(WX_JSURL, appId, scret, jscode)
	return GetWxJsOpenIdWithUrl(url)
}

func GetWxJsOpenIdWithUrl(url string) (string, string, string, error) {
	// 使用超时连接
	client := http.Client{ Timeout: time.Second * 20 }
	resp, err := client.Get(url)
	if nil != err {
		return "", "", "", err
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if nil != err {
		return "", "", "", err
	}
	var result map[string]interface{}
	err = json.Unmarshal([]byte(body), &result)
	if err != nil {
		return "", "", "", err
	}
	if errcode, ok := result["errcode"]; ok {
		code := int(errcode.(float64))
		if 0 != code {
			return "", "", "", errors.New("err code " + strconv.Itoa(code))
		}
	}
	openid, ok := result["openid"]
	if !ok {
		return "", "", "", errors.New("no openid")
	}
	key, ok := result["session_key"]
	if !ok {
		return "", "", "", errors.New("no session_key")
	}
	unionid, ok := result["unionid"]
	if !ok {
		unionid = ""
	}
	return openid.(string), key.(string), unionid.(string), nil
}

// 移动应用获取 openId, token, unionid
// code: 由小程序传递过来的登录凭证
// {
//   "access_token": "ACCESS_TOKEN",
//   "expires_in": 7200,
//   "refresh_token": "REFRESH_TOKEN",
//   "openid": "OPENID",
//   "scope": "SCOPE",
//   "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
// }

func GetWxOauth2OpenId(appId string, scret string, code string) (string, string, string, error) {
	url := fmt.Sprintf(WX_OAUTH2, appId, scret, code)
	return GetWxOauth2OpenIdWithUrl(url)
}

func GetWxOauth2OpenIdWithUrl(url string) (string, string, string, error) {
	// 使用超时连接
	client := http.Client{ Timeout: time.Second * 20 }
	resp, err := client.Get(url)
	if nil != err {
		return "", "", "", err
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if nil != err {
		return "", "", "", err
	}
	var result map[string]interface{}
	err = json.Unmarshal([]byte(body), &result)
	if err != nil {
		return "", "", "", err
	}
	if errcode, ok := result["errcode"]; ok {
		code := int(errcode.(float64))
		if 0 != code {
			return "", "", "", errors.New("err code " + strconv.Itoa(code))
		}
	}
	openid, ok := result["openid"]
	if !ok {
		return "", "", "", errors.New("no openid")
	}
	key, ok := result["access_token"]
	if !ok {
		return "", "", "", errors.New("no access_token")
	}
	unionid, ok := result["unionid"]
	if !ok {
		unionid = ""
	}
	return openid.(string), key.(string), unionid.(string), nil
}